﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data;
using System.Linq;
using System.Reflection;

public static class EntityHelper
{
    // 获取表名
    public static string GetTableName<T>()
    {
        var tableAttribute = typeof(T).GetCustomAttribute<TableAttribute>();
        return tableAttribute?.Name ?? typeof(T).Name;
    }

    // 获取所有列名
    public static List<string> GetColumns<T>()
    {
        return typeof(T).GetProperties()
                        .Where(p => p.GetCustomAttribute<ColumnAttribute>() != null)
                        .Select(p => p.GetCustomAttribute<ColumnAttribute>().Name)
                        .ToList();
    }

    // 获取属性和列名的映射
    public static Dictionary<string, PropertyInfo> GetPropertyColumnMap<T>()
    {
        return typeof(T).GetProperties()
                        .Where(p => p.GetCustomAttribute<ColumnAttribute>() != null)
                        .ToDictionary(p => p.GetCustomAttribute<ColumnAttribute>().Name, p => p);
    }

    // 获取属性名与数据库字段名的映射
    public static Dictionary<string, string> GetPropertyDatabaseColumnMap<T>()
    {
        return typeof(T).GetProperties()
                        .Where(p => p.GetCustomAttribute<ColumnAttribute>() != null)
                        .ToDictionary(p => p.Name, p => p.GetCustomAttribute<ColumnAttribute>().Name ?? p.Name);
    }

    // 将读取器映射到实体
    public static T MapReaderToEntity<T>(IDataReader reader, Dictionary<string, PropertyInfo> propertyColumnMap) where T : new()
    {
        var entity = new T();

        for (int i = 0; i < reader.FieldCount; i++)
        {
            var columnName = reader.GetName(i);
            if (propertyColumnMap.TryGetValue(columnName, out var property) && !reader.IsDBNull(i))
            {
                var value = reader.GetValue(i);
                var targetType = Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType;

                try
                {
                    var safeValue = (value == null) ? null : Convert.ChangeType(value, targetType);
                    property.SetValue(entity, safeValue);
                }
                catch (InvalidCastException ex)
                {
                    throw new InvalidCastException($"Invalid cast from '{value.GetType()}' to '{property.PropertyType}' for property '{property.Name}'.", ex);
                }
            }
        }

        return entity;
    }
}
